package com.kakame.codenews.base.util;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

/**
 * <pre>
 * <b>desc:</b> 系统一些通用的工具类 
 * <b>auth:</b> 何家明
 * <b>date:</b> 2018年6月5日 下午2:06:22
 * </pre>
 */
@SuppressWarnings("unchecked")
public class SystemUtil {

	/**
	 * <pre>
	 * <b>desc:</b> 返回一个String, Object的HashMap 
	 * <b>auth:</b> 何家明
	 * <b>date:</b> 2018年6月5日 下午2:07:22
	 * </pre>
	 * 
	 * @return
	 */
	public static Map<String, Object> getSOHashMap() {
		return new HashMap<String, Object>();
	}

	/**
	 * <pre>
	 * <b>desc:</b> 将字符串数组转成逗号分隔的字符串 
	 * <b>auth:</b> 何家明
	 * <b>date:</b> 2018年6月6日 下午5:43:36
	 * </pre>
	 * 
	 * @param array
	 * @return
	 */
	public static String convertArrayToString(String[] array) {
		StringBuilder sb = new StringBuilder();
		for (String string : array) {
			sb.append(string).append(",");
		}
		sb.deleteCharAt(sb.length() - 1);
		return sb.toString();
	}

	/**
	 * <pre>
	 * <b>desc:</b> 将obj对象转换成Map<String, Object> 
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月8日 上午11:10:13
	 * </pre>
	 * 
	 * @param mapObj
	 * @return 无论如果都会返回一个map，故外面无需考虑空指针问题
	 */
	public static Map<String, Object> convertObjectToMapSO(Object mapObj) {
		if (mapObj == null || !(mapObj instanceof Map)) {
			return getSOHashMap();
		}
		return (Map<String, Object>) mapObj;

	}

	/**
	 * 多余字数省略号
	 * @author 何家明 2018年7月9日 下午9:46:41
	 * @param content
	 * @return
	 */
	public static String ellipsisContent(String content) {
		if(StringUtils.isNotBlank(content)) {
			int size = 100;
			if(content.length() > size) {
				content = content.substring(0, size);
				content += "...";
			}
			return content;
		}
		return "";
	}
	
	/**
	 * 从html中提取纯文本  
	 * @author 何家明 2018年7月9日 下午9:43:15
	 * @param inputString
	 * @return
	 */
	public static String htmlToText(String inputString) {
		String htmlStr = inputString; // 含html标签的字符串
		String textStr = "";
		Pattern p_script;
		Matcher m_script;
		Pattern p_style;
		Matcher m_style;
		Pattern p_html;
		Matcher m_html;
		String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
		String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
		String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
		p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
		m_script = p_script.matcher(htmlStr);
		htmlStr = m_script.replaceAll(""); // 过滤script标签
		p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
		m_style = p_style.matcher(htmlStr);
		htmlStr = m_style.replaceAll(""); // 过滤style标签
		p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
		m_html = p_html.matcher(htmlStr);
		htmlStr = m_html.replaceAll(""); // 过滤html标签
		textStr = htmlStr;
		// 剔除空格行
		textStr = textStr.replaceAll("[ ]+", " ");
		textStr = textStr.replaceAll("(?m)^\\s*$(\\n|\\r\\n)", "");
		return textStr;// 返回文本字符串
	}
	

	/**
	 * 利用反射实现JavaBean的自动赋值
	 * 
	 * @author 何家明 2018年7月1日 下午9:38:43
	 * @param obj
	 *            需要进行赋值的对象
	 * @param value
	 *            属性值
	 * @param field
	 * @param fieldClass
	 */
	public static <T> void setFieldValue(T obj, Object value, Field field) {
		try {
			field.set(obj, value);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
	
	/**
     * 利用反射实现JavaBean的自动取值
     * 
     * @author 何家明 2018年7月1日 下午9:38:43
     * @param obj
     *            需要进行赋值的对象
     * @param value
     *            属性值
     * @param field
     * @param fieldClass
	 * @return 
     */
    public static <T> Object getFieldValue(T obj, Field field) {
        try {
            return field.get(obj);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

	/**
	 * 将实体bean转换成sql参数map
	 * @author 何家明 2018年7月8日 下午6:05:41
	 * @param bean
	 * @return
	 */
	public static Map<String, Object> convertBeanToParamMap(Object bean) {
		if (bean == null) {
			return null;
		}
		Map<String, Object> map = new LinkedHashMap<String, Object>();
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				// 过滤class属性
				if (!key.equals("class")) {
				    // 这种情况说明只有get方法，没有set方法，是扩展字段
				    if(null == property.getWriteMethod()) {
				        continue;
				    }
					// 得到property对应的getter方法
					Method getter = property.getReadMethod();
					Object value = getter.invoke(bean);
					if(value != null && !"null".equals(value) && !"".equals(value)) {
						map.put(key, value);
					}
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}

	/**
	 * <pre>
	 * <b>desc:</b> 根据经验值生成用户等级的算法 
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年7月12日 下午5:48:22
	 * </pre>
	 * @param userExp
	 * @return
	 */
    public static Integer generateUserLevel(Integer userExp) {
        if(userExp == null) {
            userExp = 0;
        }
        Integer[] level = {0, 100, 300, 800, 2000, 4000, 6400, 10000};
        for(int i = 0; i < level.length; i++) {
            if(i == level.length - 1) {
                if(userExp > level[i]) {
                    return i + 1;
                }
            } else {
                if(level[i] <= userExp && level[i + 1] > userExp) {
                    return i;
                }
            }
        }
        return -1;
    }
    
    /**
     * <pre>
     * <b>desc:</b> 根据新对象，更新老对象中的值 
     * <b>auth:</b> ex-hejm
     * <b>date:</b> 2018年7月13日 下午5:59:21
     * </pre>
     * @param oldObj
     * @param newObj
     * @param ignoreNull 属性为空的时候，是否赋值
     */
    public static <T> void reloadObject(T oldObj, T newObj, boolean ignoreNull) {
        if(oldObj == null) {
            return;
        }
        Field[] fields = oldObj.getClass().getDeclaredFields();
        for (Field field : fields) {
        	if("serialVersionUID".equals(field.getName())) {
        		continue;
        	}
        	field.setAccessible(true);
            Object fieldValue = getFieldValue(newObj, field);
            if(ignoreNull) {
                if(fieldValue == null) {
                    continue;
                }
            }
            setFieldValue(oldObj, fieldValue, field);
        }
    }
    
    /**
     * <pre>
     * <b>desc:</b> 判断数组里面的元素是不是都是基本类型（包括String） 
     * <b>auth:</b> ex-hejm
     * <b>date:</b> 2018年7月27日 下午1:21:57
     * </pre>
     * @param objects
     * @return
     */
    public static boolean isBaseType(Object[] objects) {
        for (Object object : objects) {
            if(!isBaseType(object)) {
                return false;
            }
        }
        return true;
    }
    
    /**
    * 判断object是否为基本类型（包括String）
    * @param object
    * @return
    */
    public static boolean isBaseType(Object object) {
        Class<?> className = object.getClass();
        return isBaseType(className);
    }
    
    /**
     * <pre>
     * <b>desc:</b> 是否为基本类型（包括String）
     * <b>auth:</b> ex-hejm
     * <b>date:</b> 2018年8月2日 下午3:56:03
     * </pre>
     * @param clazz
     * @return
     */
    public static <T> boolean isBaseType(Class<T> className) {
        if (className.equals(java.lang.Integer.class) ||
            className.equals(java.lang.Byte.class) ||
            className.equals(java.lang.Long.class) ||
            className.equals(java.lang.Double.class) ||
            className.equals(java.lang.Float.class) ||
            className.equals(java.lang.Character.class) ||
            className.equals(java.lang.Short.class) ||
            className.equals(java.lang.Boolean.class) ||
            className.equals(java.lang.String.class)
            ) {
            return true;
        }
        return false;
    }
    
    /**
     * <pre>
     * <b>desc:</b> 判断数组是否为空 
     * <b>auth:</b> ex-hejm
     * <b>date:</b> 2018年7月27日 下午1:33:37
     * </pre>
     * @param objects
     * @return
     */
    public static boolean isNull(Object[] objects) {
        if(objects == null || objects.length == 0) {
            return true;
        }
        return false;
    }
    
    /**
     * <pre>
     * <b>desc:</b> 计算数组的和
     * <b>auth:</b> ex-hejm
     * <b>date:</b> 2018年8月2日 下午2:32:49
     * </pre>
     * @param batchUpdate
     * @return
     */
    public static int sumArray(int[] batchUpdate) {
        int sum = 0;
        if(batchUpdate != null) {
            for (int i : batchUpdate) {
                sum += i;
            }
        }
        return sum;
    }
}
